package com.fooddiary.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.springframework.stereotype.Component;

/**
 * Application utility class <br>
 * @author Created by andrey.kuznetsov <br>
 * @author Last modified by $Author$ <br>
 * @author Last modified on $Date$ at revision $Revision$ <br>
 */
@Component
public class ApplicationUtils {
	
	private static final String DATE_FORMAT_DMY = "dd-MM-yyyy";
	private static final String DATE_FORMAT_HHMM = "HH:mm";

	/**
	 * Converts date from long to string in DMY format <br>
	 * @param p_date - date in milliseconds; {@link Long} <br>
	 * @return {@link String}
	 */
	public String getDateDMYFromLong(Long p_date){
		return getDateFromLong(p_date, DATE_FORMAT_DMY);
	}
	
	/**
	 * Convert date from long to string in given format <br>
	 * @param p_date - date in milliseconds; {@link Long} <br>
	 * @param p_format - date format; {@link String} <br>
	 * @return date in string format; {@link String}
	 */
	private String getDateFromLong(Long p_date, String p_format){
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(p_date);
		DateFormat dateFormat = new SimpleDateFormat(p_format);
		return dateFormat.format(calendar.getTime());
	} 
	
	/**
	 * Convers date from string in dd-MM-yyyy fromat to long <br>
	 * @param p_date - date in dd-MM-yyyy format; {@link String} <br>
	 * @return date in milliseconds; {@link Long}
	 * @throws ParseException 
	 */
	public Long parseDateDMYToLong(String p_date) throws ParseException{
		DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_DMY);
		Date date = dateFormat.parse( p_date );
		return date.getTime();
	}
	
	/**
	 * Convers time from string in HH:MM fromat to long <br>
	 * @param p_date - time in HH:MM format; {@link String} <br>
	 * @return time in milliseconds; {@link Long}
	 * @throws ParseException 
	 */
	public Long parseDateHHMMToLong(String p_date) throws ParseException{
		DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_HHMM);
		Date date = dateFormat.parse( p_date );
		return date.getTime();
	}
	
	/**
	 * Returns date day ago  in milliseconds <br>
	 * @param p_date - current date in milliseconds; {@link Long} <br>
	 * @return {@link Long}
	 */
	public Long getDayBefore(Long p_date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis( p_date );
		if(calendar.get(Calendar.DAY_OF_YEAR) == 1){
			calendar.set(calendar.get( Calendar.YEAR) - 1, Calendar.DECEMBER, calendar.getActualMaximum( Calendar.DAY_OF_MONTH ));
		}else{
			calendar.set( Calendar.DAY_OF_YEAR, calendar.get( Calendar.DAY_OF_YEAR ) - 1 );
		}	
		return calendar.getTimeInMillis();
	}
	
	/**
	 * Returns date week ago in milliseconds <br>
	 * @param p_date -current date in milliseconds; {@link Long} <br> 
	 * @return {@link Long}
	 */
	public Long getWeekBefore(Long p_date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis( p_date );
		if(calendar.get( Calendar.WEEK_OF_YEAR ) == 1 ){
			calendar.set( Calendar.YEAR, calendar.get( Calendar.YEAR ) -1 );
			calendar.set( Calendar.WEEK_OF_YEAR, calendar.getActualMaximum( Calendar.WEEK_OF_YEAR ) );
		}else{
			calendar.set( Calendar.WEEK_OF_YEAR, calendar.get( Calendar.WEEK_OF_YEAR ) - 1 );
		}
		return calendar.getTimeInMillis();
	}
	
	/**
	 * Return date month ago in milliseconds <br>
	 * @param p_date - current date in milliseconds; {@link Long} <br>
	 * @return {@link Long}
	 */
	public Long getMonthBefore(Long p_date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis( p_date );
		if(calendar.get(Calendar.MONTH) == Calendar.JANUARY){
			calendar.set(calendar.get( Calendar.YEAR) - 1, Calendar.DECEMBER, calendar.get( Calendar.DAY_OF_MONTH ));
		}else{
			calendar.set(Calendar.MONTH, calendar.get( Calendar.MONTH ) - 1 );
		}	
		return calendar.getTimeInMillis();
	}
	
	/**
	 * Returns start of give day in millisecond <br>
	 * @param p_date - date in millisecond; {@link Long} <br>
	 * @return start of given day in millisecond; {@link Long}
	 */
	public Long getStartOfDay(Long p_date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis( p_date );
		calendar.set(Calendar.HOUR, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTimeInMillis();
	}
	
	/**
     * Checks if the calendar object is same date as today <br>
     * @param cal the calendar object; @li {@link Calendar} <br>
     * @return true if the calendar object is the same date as today.
     */
    public boolean isToday(Calendar cal) {
        Calendar today = Calendar.getInstance();
        return today.get(Calendar.YEAR) == cal.get(Calendar.YEAR) 
        	&& today.get(Calendar.DAY_OF_YEAR) == cal.get(Calendar.DAY_OF_YEAR);
    }
    
    /**
     * Return current date and time in milliseconds <br>
     * @return {@link Long}
     */
    public Long getCurrentTimeInMilliseconds(){
    	return Calendar.getInstance().getTimeInMillis();
    }

}
